/* $Header: sx_cmds.c,v 2.4 02/04/25 13:43:41 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME: sx_cmds.c                                              */
/* ============                                                        */
/*                                                                     */
/* Author:  Bob Cook                                                   */
/*                                                                     */
/* MODULE PURPOSE: This module will handle the digital data commands.  */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

/*
 */

/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/

#include <typedefs.h>
#include <stddef.h>
#include <p_wkfile.h>
#include <wkfile.h>
#include <ramps.h>
#include <zone_config.h>
#include <config.h>
#include <zone_status.h>
#include <status.h>
#include <readiness.h>

#include <error.h>
#include <i_op.h>
#include <sig_types.h>
#include <dig_path.h>

#include <method.h>
#include <cmd_tbls.h>

#include <sig_ui.h>

#include <mio.h>
#include <cmd_set.h>
#include <hostutil.h>
#include <cmdproc.h>

#include <exception.h>
#include <err_handler.h>
#include <512.h>

/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/



/*****************************/
/*   TYPEDEFS                */
/*****************************/

typedef struct
{
   BIT8     pending;
   BIT8     comm_port;
   INT16    dsap;
   INT16    ssap;
   INT16    opcode;
   U_INT16  points;
   U_INT16  timeout;
} RD_PENDING, *pRD_PENDING;


/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/

TMP_MSG_TYPE    Tmp_Msg;
RD_PENDING      Signal1_Rd_Pending;
RD_PENDING      Signal2_Rd_Pending;
RD_PENDING      SignalP_Rd_Pending;

/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/

extern SIGNAL_CB_TYPE compress_cb[3];
extern SIGNAL_CB_TYPE uncompress_cb[3];
extern SIGBUF_TYPE  SigBuf_V[NUM_SIGNALS]; /*create vars for SigBuf1, SigBuf2 & SigBufP*/

/*****************************/
/*   LOCAL DEFINES           */
/*****************************/

/* if BC_DEBUG is defined debug buffers are created and statics become global */
#define BC_DEBUG

/* when debugging make variables global for emulator testing */
#ifdef BC_DEBUG
#   define SCOPE
#else
#   define  SCOPE  static
#endif


/*****************************/
/*   STATIC VARIABLES        */
/*****************************/



/*****************************/
/*   MACROS                  */
/*****************************/


/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/



/***********************************************************************/
/* FUNCTION: InitializeSxRD                                            */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Initialization for delayed response to SxRD command        */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

void InitializeSxRD(void)
{
Signal1_Rd_Pending.pending = FALSE;
Signal2_Rd_Pending.pending = FALSE;
SignalP_Rd_Pending.pending = FALSE;
}



/***********************************************************************/
/* FUNCTION: DoSXEO                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Echo command.                                              */
/*                                                                     */
/* RETURNED VALUE: length of response string                           */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 DoSXEO(CMD_TYPE *p_cmd,BIT8  *p_resp_parm)
{
U_INT16 len;

   len = 0;

   if (p_cmd->parmv[0] == 1)
   {
      len = PutAsciiParam((BIT8 *)"\"", p_resp_parm);
      len += PutAsciiParam((BIT8 *)&(p_cmd->parms[p_cmd->parmv[1]]),
                                     p_resp_parm+len);
      len += PutAsciiParam((BIT8 *)"\"", p_resp_parm+len);
      return len;
   }
   else
   {
      CmdErrorHandler(p_cmd,1,INVALID_PARAM);
      return NO_RESPONSE;
   }
}

/***********************************************************************/
/* END FUNCTION: DoSXEO                                                */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: DoSxRS                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SxRS command.                                */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/***********************************************************************/

INT16 DoSxRS(U_INT8  signal)
{
   INTERRUPTS_OFF;
      switch (signal)
      {
      case SIGNAL1:
         InitSignal_1_DigitalPath();
         ClearNewException(SIGBUF1_OVERFLOW);
         break;
      case SIGNAL2:
         InitSignal_2_DigitalPath();
         ClearNewException(SIGBUF2_OVERFLOW);
         break;
      case SIGNALP:
         InitSignal_P_DigitalPath();
/* revisit - need to create a new exception for signal buffer overflow */
/*       ClearNewException(SIGBUFP_OVERFLOW);                          */
         break;
      default:
         /* invalid command - ignore command */
         ;
      }
   INTERRUPTS_ON;
   return  NO_RESPONSE;
}

/***********************************************************************/
/* END FUNCTION: DoSxRS                                                */
/***********************************************************************/


/***********************************************************************/
/* FUNCTION: DoSSRS                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SSRS command which will reset the data       */
/*          buffer for both S1 and S2 channels.                        */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/***********************************************************************/

INT16 DoSSRS(void)
{
   INTERRUPTS_OFF;
      InitSignal_1_DigitalPath();
      ClearNewException(SIGBUF1_OVERFLOW);

      InitSignal_2_DigitalPath();
      ClearNewException(SIGBUF2_OVERFLOW);

      InitSignal_P_DigitalPath();
/* revisit - need to create new exception for signal P buffer overflow */
/*    ClearNewException(SIGBUFP_OVERFLOW);                             */
   INTERRUPTS_ON;

   return  NO_RESPONSE;
}

/***********************************************************************/
/* END FUNCTION: DoSSRS                                                */
/***********************************************************************/

/***********************************************************************/
/* FUNCTION: DoSSDT                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Puts IQ in Digital Path Test Mode which outputs a ramp     */
/*          which covers the full data range of IQ.                    */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/***********************************************************************/

INT16 DoSSDT(void)
{
   INTERRUPTS_OFF;
      InitSignal_1_DigitalPath();
      ClearNewException(SIGBUF1_OVERFLOW);

      InitSignal_2_DigitalPath();
      ClearNewException(SIGBUF2_OVERFLOW);

      InitSignal_P_DigitalPath();
/* revisit - need to create new exception for signal P buffer overflow */
/*    ClearNewException(SIGBUFP_OVERFLOW);                             */
   INTERRUPTS_ON;

   DigitalPathTestMode = 1;

   return  NO_RESPONSE;
}

/***********************************************************************/
/* END FUNCTION: DoSSDT                                                */
/***********************************************************************/


/***********************************************************************/
/* FUNCTION: DoSxRDBin                                                 */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SxRDBin command.                             */
/* the format of the response msg is <msg hdr><data hdr><binary data>  */
/*                                                                     */
/* RETURNED VALUE:  number of bytes added to message                   */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 DoSxRDBin(U_INT8  signal, CMD_TYPE  *p_cmd,
                          BIT8 *p_resp_parm,U_INT16 max_resp_len)
{
   RD_RESP_BIN_TYPE *p_data_hdr;
   U_INT16          *p_msg_data;
   U_INT16           num_pts;
   U_INT16           max_pts;
   INT32             req_num_pts;
   U_INT16           done;
   UI_ERR            error;
   INT16             temp16;   /* used for compressed value */
   U_INT32           temp32;
   /*
    * p_resp_parm points to first byte after dest,source,opcode,space
    *  characters of the response msg.  However, in binary mode the
    *  space should not be present. To fake out the standard routines,
    *  the pointer is decremented by one to remove the space.
    *  In addition, the byte count returned was decremented by one to
    *  end up with the correct length.
    */
   p_resp_parm--;   /* remove space after opcode */


   /* p_resp_parm points to the parameter section of the response msg. */
   /* Set up pointers to the data hdr and data sections of response msg. */
   p_data_hdr = (RD_RESP_BIN_TYPE *)(p_resp_parm);
   p_msg_data = (U_INT16 *)(p_resp_parm + RD_BIN_MSG_HDR_LEN);

   /* initialize data header */
   *p_resp_parm  = 0;          /* zero status word */
   *(p_resp_parm + 1) = 0;

   p_data_hdr->start_pos = 0;
   p_data_hdr->start_delta = 0;

   /* determine number of requested points from the 1st parameter of command */
   if ( (p_cmd->parmv[0]) > 0)
   {
      if( StrLen( &p_cmd->parms[p_cmd->parmv[1]]) != 0 )
      {
         error = DecToInt( &p_cmd->parms[p_cmd->parmv[1]],0,&req_num_pts );
         if(error != OK)
         {
            CmdErrorHandler(p_cmd,1,error);
            return NO_RESPONSE;
         }
         max_pts = (max_resp_len - BIN_DATA_HDR_SIZE) / BIN_MAX_PT_SIZE;
         if( req_num_pts > max_pts )
         {
            req_num_pts = max_pts;
         }
      }
      else
      /* number of points not given */
      {
         req_num_pts = 1;
      }
   }
   else
   {
      /* only SxRD given, use default number of points */
      req_num_pts = 1;
   }
   done = 0;
   num_pts = 0;
   while ( num_pts < req_num_pts && !done )

   {
      INTERRUPTS_OFF;
      if ( SigBuf_Point_Count[signal] > 0 )
      {
         /* Retrieve next value and determine if it's compressed */
         /*     or full point */
           GetBuf(SigBuf_V[signal],&temp16);

         switch(temp16)
         {
         case COMPRESS_FULL_POINT_MARKER:
            /* full point marker */
            /* output 6 byte data point and set the variable */
            /*     called point_last to the 6 byte data point */
            /* get MSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            *p_msg_data = temp16;
            p_msg_data++;
            uncompress_cb[signal].point_last.hi = (INT32)temp16;
            /* get middle byte */
            GetBuf(SigBuf_V[signal],&temp16);
            *p_msg_data = temp16;
            p_msg_data++;
            uncompress_cb[signal].point_last.lo = (U_INT16)temp16;
            uncompress_cb[signal].point_last.lo <<= 16;
            /* get LSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            *p_msg_data = temp16;
            p_msg_data++;
            uncompress_cb[signal].point_last.lo |= (U_INT16)temp16;
            ResetUncompress(signal);
            num_pts++;
            break;
         case COMPRESS_START_MARKER:
            /* start marker */

            /* get MSByte of time count for start delta */
            GetBuf(SigBuf_V[signal],&temp32);
            temp32 = temp32 << 16;
            /* get LSByte of time count for start delta */
            GetBuf(SigBuf_V[signal],&temp16);
            temp32 |= (U_INT16)temp16;
            p_data_hdr->status.bits.start = 1;
            /* Multiply the start delta count by the time per count. */
            /*   This gives the start_delta in micro-sec(62.5 us/ct). */
            p_data_hdr->start_delta = temp32 * 125;
            p_data_hdr->start_delta /= 2;

            /* get start point and increase point count */
            /* output 6 byte data point and set point_last to */
            /*      6 byte data point */
            /* get MSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            *p_msg_data = temp16;
            p_msg_data++;
            /* sign extend */
            uncompress_cb[signal].point_last.hi = (INT32)temp16;
            /* get middle byte */
            GetBuf(SigBuf_V[signal],&temp16);
            *p_msg_data = temp16;
            p_msg_data++;
            uncompress_cb[signal].point_last.lo = temp16;
            uncompress_cb[signal].point_last.lo <<= 16;
            /* get LSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            *p_msg_data = temp16;
            p_msg_data++;
            uncompress_cb[signal].point_last.lo |= (U_INT16)temp16;
            ResetUncompress(signal);
            num_pts++;
            p_data_hdr->start_pos = num_pts;

            break;
         case COMPRESS_STOP_MARKER:
            /* stop marker */
            /* get set status and end msg */
            p_data_hdr->status.bits.stop = 1;
            done = 1;
            break;
         case COMPRESS_START_STOP_MARKER:
            /* start/stop marker */
            /* set status and end msg */
            p_data_hdr->status.bits.start_stop = 1;
            done = 1;
            break;
         default:
            ConvCompressTo64(&temp16,&uncompress_cb[signal].diff2);
            Uncompress_Diff2(signal);
            *p_msg_data = (INT16)uncompress_cb[signal].point.hi;
            p_msg_data++;
            *p_msg_data=(INT16)(uncompress_cb[signal].point.lo>>16);
            p_msg_data++;
            *p_msg_data = (INT16)uncompress_cb[signal].point.lo;
            p_msg_data++;
            /* incr num pts */
            num_pts++;
            break;
         } /* switch */

         /*
          * Decrease buffer count.
          *   Count includes:
          *      1. data points
          *      2. stop markers
          *      3. stop/start markers
          */

         SigBuf_Point_Count[signal]--;
      }
      else
      {
         done = 1;
      }
      INTERRUPTS_ON;
   }


   p_data_hdr->pt_count = num_pts;
   p_data_hdr->status.bits.data_acq = (Acq_On[signal] == TRUE) ? 1 : 0;
   p_data_hdr->status.bits.run_state = (BIT8)Run_State;
   if( Scc_Run == TRUE )
   {
      p_data_hdr->status.bits.scc_state = 1;
   }
   else
   {
      p_data_hdr->status.bits.scc_state = 0;
   }
   p_data_hdr->status.bits.gc_rdy = (BIT8)InternalReadyEval();
   p_data_hdr->status.bits.param_mod = Parameter_Modified[Cmd_Port].bits.gc_param;
   p_data_hdr->status.bits.buf_ovrflw = (SigBuf_Overflow[signal]==TRUE)?1:0;

   INTERRUPTS_OFF;
      p_data_hdr->pts_remaining = SigBuf_Point_Count[signal];
   INTERRUPTS_ON;

   /* reduce count by one to compensate for removing space char */
   return(RD_BIN_MSG_HDR_LEN + (6 * num_pts) -1);

}

/***********************************************************************/
/* END FUNCTION: DoSxRDBIN                                             */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: DoSxRDHexDec                                              */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the Hex and Dec formats for SxRD command.        */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 DoSxRDHexDec(U_INT8  signal, CMD_TYPE  *p_cmd,
                          BIT8 *p_resp_parm,U_INT16 max_resp_len)
{

   BIT8             *p_dec_data;
   BIT8             *p_tmp_msg;
   BIT8              point_size;
   U_INT16           num_pts;
   U_INT16           pt_index;
   U_INT16           done;
   U_INT16           bytes_remaining;
   UI_ERR            error;
   INT16             temp16;   /* used for compressed value */
   U_INT32           temp32;
   U_INT16           num_char;
   U_INT16           point;
   U_INT16           length;
   U_INT16           byte;
   U_INT8            value;
   U_INT8            nibble;
   INT32             req_num_pts;


   (void) max_resp_len;


   /**********************************************************************/
   /**********      Determine Number Of Points Requested       ***********/
   /**********************************************************************/

   /* determine number of requested points from the 1st parameter of command */
   if ( (p_cmd->parmv[0]) > 0)
   {
      if( StrLen( &p_cmd->parms[p_cmd->parmv[1]]) != 0 )
      {
         error = DecToInt( &p_cmd->parms[p_cmd->parmv[1]],0,&req_num_pts );
         if(error != OK)
         {
            CmdErrorHandler(p_cmd,1,error);
            return NO_RESPONSE;
         }
      }
      else
      /* number of points not given */
      {
         req_num_pts = 1;
      }
   }
   else
   {
      /* only SxRD given, use default number of points */
      req_num_pts = 1;
   }

   /* set up number of bytes remaining in packet; used to prevent overflow */
   switch (Data_Format[signal])
   {
   case HEX:
         /* remove data header size */
         bytes_remaining = max_resp_len - HEX_DATA_HDR_SIZE;
      break;

   default:
   case DEC:
         /* remove worst case data header size */
         bytes_remaining = max_resp_len - DEC_DATA_HDR_SIZE;
      break;
   }

   /**********************************************************************/
   /**********                  Get Data Points                ***********/
   /**********************************************************************/


   done = 0;
   num_pts = 0;
   /* initialize temperary data  */
   Tmp_Msg.hdr.status.word = 0;
   Tmp_Msg.hdr.start_pos = 0;
   Tmp_Msg.hdr.start_delta = 0;

   /* while more points to send and packet is not full(use DEC since larger)*/
   while( num_pts<req_num_pts && bytes_remaining>DEC_MAX_PT_SIZE && !done )
   {
      INTERRUPTS_OFF;
      if ( SigBuf_Point_Count[signal] > 0 )
      {
         /* Retrieve next value and determine if it's compressed */
         /*     or full point */
           GetBuf(SigBuf_V[signal],&temp16);

         switch(temp16)
         {
         case COMPRESS_FULL_POINT_MARKER:
            /* full point marker */
            /* output 6 byte data point and set the variable */
            /*     called point_last to the 6 byte data point */
            /* get MSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.point[num_pts].word[0] = temp16;
            uncompress_cb[signal].point_last.hi = (INT32)temp16;
            /* get middle byte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.point[num_pts].word[1] = temp16;
            uncompress_cb[signal].point_last.lo = (U_INT16)temp16;
            uncompress_cb[signal].point_last.lo <<= 16;
            /* get LSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.point[num_pts].word[2] = temp16;
            uncompress_cb[signal].point_last.lo |= (U_INT16)temp16;
            ResetUncompress(signal);
            num_pts++;
            break;
         case COMPRESS_START_MARKER:
            /* start marker */

            /* get MSByte of time count for start delta */
            GetBuf(SigBuf_V[signal],&temp32);
            temp32 = temp32 << 16;
            /* get LSByte of time count for start delta */
            GetBuf(SigBuf_V[signal],&temp16);
            temp32 |= (U_INT16)temp16;
            Tmp_Msg.hdr.status.bits.start = 1;
            /* Multiply the start delta count by the time per count. */
            /*   This gives the start_delta in micro-sec(62.5 us/ct). */
            Tmp_Msg.hdr.start_delta = temp32 * 125;
            Tmp_Msg.hdr.start_delta /= 2;

            /* get start point and increase point count */
            /* output 6 byte data point and set point_last to */
            /*      6 byte data point */
            /* get MSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.point[num_pts].word[0] = temp16;
            /* sign extend */
            uncompress_cb[signal].point_last.hi = (INT32)temp16;
            /* get middle byte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.point[num_pts].word[1] = temp16;
            uncompress_cb[signal].point_last.lo = temp16;
            uncompress_cb[signal].point_last.lo <<= 16;
            /* get LSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.point[num_pts].word[2] = temp16;
            uncompress_cb[signal].point_last.lo |= (U_INT16)temp16;
            ResetUncompress(signal);
            num_pts++;
            Tmp_Msg.hdr.start_pos = num_pts;

            break;
         case COMPRESS_STOP_MARKER:
            /* stop marker */
            /* get set status and end msg */
            Tmp_Msg.hdr.status.bits.stop = 1;
            done = 1;
            break;
         case COMPRESS_START_STOP_MARKER:
            /* start/stop marker */
            /* set status and end msg */
            Tmp_Msg.hdr.status.bits.start_stop = 1;
            done = 1;
            break;
         default:
            ConvCompressTo64(&temp16,&uncompress_cb[signal].diff2);
            Uncompress_Diff2(signal);
            Tmp_Msg.data.point[num_pts].word[0] =
                               (INT16)uncompress_cb[signal].point.hi;
            Tmp_Msg.data.point[num_pts].word[1] =
                               (INT16)(uncompress_cb[signal].point.lo>>16);
            Tmp_Msg.data.point[num_pts].word[2] =
                               (INT16)uncompress_cb[signal].point.lo;
            /* incr num pts */
            num_pts++;
            break;
         } /* switch */

         /************ ESTIMATE NUMBER OF BYTES FOR THIS POINT ***************/
         if (num_pts != 0)
         {
            pt_index = num_pts - 1;

            /* find approximate size of point to estimate when packet is full */
            if( Data_Format[signal] == DEC )
            {
               if( ((U_INT16)Tmp_Msg.data.point[pt_index].word[0] & 0x8000) == 0 )
               {
                  /* positive number */
                  /* Assume 40 bit max = 1,099,511,627,775 plus comma */
                  point_size = 14;
                  if( (U_INT16)Tmp_Msg.data.point[pt_index].word[0] == 0 )
                  {
                     /* largest number = 4,294,967,295 plus comma */
                     point_size = 11;
                     if( ((U_INT16)Tmp_Msg.data.point[pt_index].word[1] & 0xFF00) == 0 )
                     {
                        /* largest number = 16,777,215 plus comma */
                        point_size = 9;
                        if( (U_INT16)Tmp_Msg.data.point[pt_index].word[1] == 0 )
                        {
                           /* largest number = 65,535 plus comma */
                           point_size = 6;
                        }
                     }
                  }
               }
               else
               {
                  /* negative number */
                  /* Assume 40 bit max  = -1,099,511,627,776 plus comma */
                  point_size = 15;
                  if((U_INT16)Tmp_Msg.data.point[pt_index].word[0] == 0xFFFF)
                  {
                     /* largest number = -4,294,967,296 plus comma */
                     point_size = 12;
                     if(((U_INT16)Tmp_Msg.data.point[pt_index].word[1] & 0xFF00) == 0xFF00)
                     {
                        /* largest number = -16,777,216 plus comma */
                        point_size = 10;
                        if((U_INT16)Tmp_Msg.data.point[pt_index].word[1] == 0xFFFF)
                        {
                           /* largest number = -65,536 plus comma */
                           point_size = 7;
                        }
                     }
                  }
               }
            }
            else
            {
               point_size = 12;
            }
            bytes_remaining = bytes_remaining - point_size;

         }

         /****************** UPDATE SIGNAL BUFFER COUNT *********************/
         /*
          * Decrease Sig buffer count.
          *   Count includes:
          *      1. data points
          *      2. stop markers
          *      3. stop/start markers
          */

         SigBuf_Point_Count[signal]--;
      }
      else
      {
         done = 1;
      }
      INTERRUPTS_ON;
   }

   /**********************************************************************/
   /**********           Set Up Output Message                 ***********/
   /**********************************************************************/

   /********* Set up header here (start or stop occured etc) **************/

   Tmp_Msg.hdr.pt_count = num_pts;
   Tmp_Msg.hdr.status.bits.data_acq = (Acq_On[signal] == TRUE) ? 1 : 0;
   Tmp_Msg.hdr.status.bits.run_state = (BIT8)Run_State;
   if( Scc_Run == TRUE )
   {
      Tmp_Msg.hdr.status.bits.scc_state = 1;
   }
   else
   {
      Tmp_Msg.hdr.status.bits.scc_state = 0;
   }
   Tmp_Msg.hdr.status.bits.gc_rdy = (BIT8)InternalReadyEval();
   Tmp_Msg.hdr.status.bits.param_mod = Parameter_Modified[Cmd_Port].bits.gc_param;
   Tmp_Msg.hdr.status.bits.buf_ovrflw = (SigBuf_Overflow[signal]==TRUE)?1:0;

   INTERRUPTS_OFF;
      Tmp_Msg.hdr.pts_remaining = SigBuf_Point_Count[signal];
   INTERRUPTS_ON;


   /*************** Set up output message here **********************/

   switch (Data_Format[signal])
   {
   case HEX:
      /*
       * p_resp_parm points to first byte after dest,source,opcode,space
       *  characters of the response msg.  However, in hex mode the
       *  space should not be present. To fake out the standard routines,
       *  the pointer is decremented by one to remove the space.
       *  In addition, the byte count returned was decremented by one to
       *  end up with the correct length.
       */
      p_resp_parm--;   /* remove space after opcode */


      p_tmp_msg = (BIT8  *)&Tmp_Msg.hdr.status.word;

      length = 0;
      for (byte = 0; byte < (2*(RD_BIN_MSG_HDR_LEN+(6*num_pts))); byte = byte + 2)
      {
         value = *p_tmp_msg++;
         nibble = value >> 4;
         *(p_resp_parm+length) = (nibble < 10) ? '0' + nibble :
            ('A' - 10) + nibble;
         length ++;
         nibble = value & 0x0F;
         *(p_resp_parm+length) = (nibble < 10) ? '0' + nibble :
            ('A' - 10) + nibble;
         length ++;
      }


      /* reduce count by one to compensate for removing space char */
      return  ((2*(RD_BIN_MSG_HDR_LEN+(6*num_pts)))-1);
      /* break; */
   case DEC:

      /* set up output message header */

      /*set up pointer to output packet move back to using space after opcode*/
      p_dec_data = p_resp_parm;

      /* output status word */
#if 0
                   512      /* bit 9-15 - not used */
      annot      = 256      /* bit 8 - annotation available flag */
      scc_state  = 128      /* bit 7 - is scc run active */
      run_state  = 16 32 64 /* bits 4-6 - run state */
      data_acq   = 8        /* bit 3 - data acquisition on flag */
      start_stop = 4        /* bit 2 - a start and stop occurred */
                            /*          without data point */
      stop       = 2        /* bit 1 - stop point in buffer */
      start      = 1        /* bit 0 - start point in buffer */
#endif

      num_char = PutIntParam(Tmp_Msg.hdr.status.word, p_dec_data, 0);
      p_dec_data += num_char;

      /* output pts_remaining */
      num_char = PutAsciiParam((BIT8 *)",", (BIT8 *)p_dec_data);
      p_dec_data += num_char;
      num_char = PutIntParam(Tmp_Msg.hdr.pts_remaining, p_dec_data, 0);
      p_dec_data += num_char;

      /* output pt_count */
      num_char = PutAsciiParam((BIT8 *)",", (BIT8 *)p_dec_data);
      p_dec_data += num_char;
      num_char = PutIntParam(num_pts, p_dec_data, 0);
      p_dec_data += num_char;

      /* output start_pos */
      num_char = PutAsciiParam((BIT8 *)",", (BIT8 *)p_dec_data);
      p_dec_data += num_char;
      num_char = PutIntParam(Tmp_Msg.hdr.start_pos, p_dec_data, 0);
      p_dec_data += num_char;

      /* output start_delta */
      num_char = PutAsciiParam((BIT8 *)",", (BIT8 *)p_dec_data);
      p_dec_data += num_char;
      num_char = PutIntParam(Tmp_Msg.hdr.start_delta, p_dec_data, 0);
      p_dec_data += num_char;

      /* convert to dec here */

      for ( point = 0 ; point < num_pts ; point++ )
      {
         if(((Tmp_Msg.data.point[point].dig_data.hi_long & 0xFFFF8000) == 0) ||
              ((Tmp_Msg.data.point[point].dig_data.hi_long & 0xFFFF8000) ==
              0xFFFF8000))
         {
           /* data may be contained in a 32 bit word */
           num_char = PutAsciiParam((BIT8 *)",", (BIT8 *)p_dec_data);
           p_dec_data += num_char;
           num_char = IntToDec(Tmp_Msg.data.point[point].int48.lo_long,
                                                     (BIT8 *)p_dec_data);
           p_dec_data += num_char;
         }
         else
         {
           /* data is larger than a 32 bit word */
           num_char = PutAsciiParam((BIT8 *)",", (BIT8 *)p_dec_data);
           p_dec_data += num_char;

           num_char = IntToDec48(Tmp_Msg.data.point[point].num_type,
                                                    (BIT8 *)p_dec_data);
           p_dec_data += num_char;

         }
      }
      return (U_INT16)(p_dec_data - p_resp_parm);
      /* break; */
   default:
      return NO_RESPONSE;
      /* break; */
   }


}

/***********************************************************************/
/* END FUNCTION: DoSxRDHexDec                                          */
/***********************************************************************/


/***********************************************************************/
/* FUNCTION: DoSxRDCmp                                                 */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SxRDCmp command (compressed data.)           */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 DoSxRDCmp(U_INT8  signal, CMD_TYPE  *p_cmd,
                          BIT8 *p_resp_parm,U_INT16 max_resp_len)
{
   BIT8             *p_tmp_msg;
   U_INT16           num_pts;
   U_INT16           num_words;
   U_INT16           bytes_remaining;
   U_INT16           done;
   UI_ERR            error;
   INT16             temp16;   /* used for compressed value */
   U_INT32           temp32;
   U_INT16           length;
   U_INT16           byte;
   U_INT8            value;
   U_INT8            nibble;
   INT32             req_num_wds;




   /**********************************************************************/
   /**********      Determine Number Of Points Requested       ***********/
   /**********************************************************************/

   /* determine number of requested words from the 1st parameter of command */
   if ( (p_cmd->parmv[0]) > 0)
   {
      if( StrLen( &p_cmd->parms[p_cmd->parmv[1]]) != 0 )
      {
         error = DecToInt( &p_cmd->parms[p_cmd->parmv[1]],0,&req_num_wds );
         if(error != OK)
         {
            CmdErrorHandler(p_cmd,1,error);
            return NO_RESPONSE;
         }
         /* must ask for atleast 8 words or 16 bytes since first point may be */
         /*   that size */
         if (req_num_wds < 8)
         {
            req_num_wds = 0;
         }
      }
      else
      /* number of words not given */
      {
         req_num_wds = 8;
      }
   }
   else
   {
      /* only SxRD given, use default number of points */
      req_num_wds = 8;
   }

   bytes_remaining = max_resp_len - CMP_DATA_HDR_SIZE;

   /**********************************************************************/
   /**********                  Get Data Points                ***********/
   /**********************************************************************/


   /* initialize temperary data  */
   Tmp_Msg.hdr.status.word = 0;
   Tmp_Msg.hdr.start_pos = 0;
   Tmp_Msg.hdr.start_delta = 0;

   done = 0;
   num_pts = 0;
   num_words = 0;
   while ( num_words<req_num_wds && bytes_remaining>CMP_MAX_PT_SIZE && !done )
   {
      INTERRUPTS_OFF;
      if ( SigBuf_Point_Count[signal] > 0 )
      {
         /* Retrieve next value and determine if it's compressed */
         /*     or full point */
           GetBuf(SigBuf_V[signal],&temp16);

         switch(temp16)
         {
         case COMPRESS_FULL_POINT_MARKER:
            /* full point marker */
            Tmp_Msg.data.compress[num_words] = temp16;
            num_words++;
            /* output 6 byte data point and set the variable */
            /*     called point_last to the 6 byte data point */
            /* get MSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.compress[num_words] = temp16;
            num_words++;
            /* get middle byte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.compress[num_words] = temp16;
            num_words++;
            /* get LSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.compress[num_words] = temp16;
            num_words++;
            num_pts++;
            bytes_remaining -= 16;
            break;
         case COMPRESS_START_MARKER:
            /* start marker */

            /* get MSByte of time count for start delta */
            GetBuf(SigBuf_V[signal],&temp32);
            temp32 = temp32 << 16;
            /* get LSByte of time count for start delta */
            GetBuf(SigBuf_V[signal],&temp16);
            temp32 |= (U_INT16)temp16;
            Tmp_Msg.hdr.status.bits.start = 1;
            /* Multiply the start delta count by the time per count. */
            /*   This gives the start_delta in micro-sec(62.5 us/ct). */
            Tmp_Msg.hdr.start_delta = temp32 * 125;
            Tmp_Msg.hdr.start_delta /= 2;

            /* full point marker (run always begins with full point */
            Tmp_Msg.data.compress[num_words] = COMPRESS_FULL_POINT_MARKER;
            num_words++;

            /* get start point and increase point count */
            /* output 6 byte data point and set point_last to */
            /*      6 byte data point */
            /* get MSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.compress[num_words] = temp16;
            num_words++;
            /* get middle byte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.compress[num_words] = temp16;
            num_words++;
            /* get LSByte */
            GetBuf(SigBuf_V[signal],&temp16);
            Tmp_Msg.data.compress[num_words] = temp16;
            num_words++;
            num_pts++;
            Tmp_Msg.hdr.start_pos = num_pts;
            bytes_remaining -= 16;
            break;
         case COMPRESS_STOP_MARKER:
            /* stop marker */
            /* get set status and end msg */
            Tmp_Msg.hdr.status.bits.stop = 1;
            done = 1;
            break;
         case COMPRESS_START_STOP_MARKER:
            /* start/stop marker */
            /* set status and end msg */
            Tmp_Msg.hdr.status.bits.start_stop = 1;
            done = 1;
            break;
         default:
            Tmp_Msg.data.compress[num_words] = temp16;
            num_words++;
            num_pts++;
            bytes_remaining -= 4;
            break;
         } /* switch */

         /*
          * Decrease buffer count.
          *   Count includes:
          *      1. data points
          *      2. stop markers
          *      3. stop/start markers
          */

         SigBuf_Point_Count[signal]--;
      }
      else
      {
         done = 1;
      }
      INTERRUPTS_ON;
   }

   /**********************************************************************/
   /**********           Set Up Output Message                 ***********/
   /**********************************************************************/

   /*  Set up header here (start or stop occured etc)  */
   Tmp_Msg.hdr.pt_count = num_pts;
   Tmp_Msg.hdr.status.bits.data_acq = (Acq_On[signal] == TRUE) ? 1 : 0;
   Tmp_Msg.hdr.status.bits.run_state = (BIT8)Run_State;
   if( Scc_Run == TRUE )
   {
      Tmp_Msg.hdr.status.bits.scc_state = 1;
   }
   else
   {
      Tmp_Msg.hdr.status.bits.scc_state = 0;
   }
   Tmp_Msg.hdr.status.bits.gc_rdy = (BIT8)InternalReadyEval();
   Tmp_Msg.hdr.status.bits.param_mod = Parameter_Modified[Cmd_Port].bits.gc_param;
   Tmp_Msg.hdr.status.bits.buf_ovrflw = (SigBuf_Overflow[signal]==TRUE)?1:0;

   INTERRUPTS_OFF;
      Tmp_Msg.hdr.pts_remaining = SigBuf_Point_Count[signal];
   INTERRUPTS_ON;


   /*         Set up output message here               */
   /*
    * p_resp_parm points to first byte after dest,source,opcode,space
    *  characters of the response msg.  However, in hex mode the
    *  space should not be present. To fake out the standard routines,
    *  the pointer is decremented by one to remove the space.
    *  In addition, the byte count returned was decremented by one to
    *  end up with the correct length.
    */
   p_resp_parm--;   /* remove space after opcode */

   p_tmp_msg = (BIT8  *)&Tmp_Msg.hdr.status.word;

   length = 0;
   for (byte = 0; byte < (RD_BIN_MSG_HDR_LEN+(2*num_words)); byte++)
   {
      value = *p_tmp_msg++;
      nibble = value >> 4;
      *(p_resp_parm+length) = (nibble < 10) ? '0' + nibble :
         ('A' - 10) + nibble;
      length ++;
      nibble = value & 0x0F;
      *(p_resp_parm+length) = (nibble < 10) ? '0' + nibble :
         ('A' - 10) + nibble;
      length ++;
   }

   /* reduce count by one to compensate for removing space char */
   return  ((2*(RD_BIN_MSG_HDR_LEN+(2*num_words)))-1);

}

/***********************************************************************/
/* END FUNCTION: DoSxRDCmp                                             */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: DoSxSR                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SxSR command.                                */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 DoSxSR(U_INT8  signal)
{
   INTERRUPTS_OFF;
      Acq_On[signal] = TRUE;
   INTERRUPTS_ON;
   return  NO_RESPONSE;
}

/***********************************************************************/
/* END FUNCTION: DoSxSR                                                */
/***********************************************************************/


/***********************************************************************/
/* FUNCTION: DoSSSR                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SSSR command which will turn on data         */
/*          acquisition for both data channels.                        */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/***********************************************************************/

INT16 DoSSSR(void)
{
   INTERRUPTS_OFF;
      Acq_On[SIGNAL1] = TRUE;
      Acq_On[SIGNAL2] = TRUE;
      Acq_On[SIGNALP] = TRUE;
   INTERRUPTS_ON;
   return  NO_RESPONSE;
}

/***********************************************************************/
/* END FUNCTION: DoSSSR                                                */
/***********************************************************************/


/***********************************************************************/
/* FUNCTION: DoSxSP                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SxSP command.                                */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16  DoSxSP(U_INT8  signal)
{
   INTERRUPTS_OFF;
      Acq_On[signal] = FALSE;
   INTERRUPTS_ON;
   return  NO_RESPONSE;
}

/***********************************************************************/
/* END FUNCTION: DoSxSP                                                */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: DoSSSP                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SxSP command.                                */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/***********************************************************************/

INT16  DoSSSP(void)
{
   INTERRUPTS_OFF;
      Acq_On[SIGNAL1] = FALSE;
      Acq_On[SIGNAL2] = FALSE;
      Acq_On[SIGNALP] = FALSE;
   INTERRUPTS_ON;
   return  NO_RESPONSE;
}

/***********************************************************************/
/* END FUNCTION: DoSSSP                                                */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: SetDataRate                                               */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

UI_ERR SetDataRate(pSIG_TABLE  p_signal, U_INT32 data_ratex10)
{
UI_ERR   error;

   /*
    * Set closest data rate above the received data rate.
    * For efficiency first determine if rate is > 20 or < 1, then compare
    *     to proper ranges to find setting.
    */


   if( data_ratex10 > 200 )
   {
      /*****************************/
      /* data rate greater than 20 */
      /*****************************/
         if (data_ratex10 > 2000)  error = SetSignalDataRate (p_signal,RATE_500HZ);
         else
            if( data_ratex10 > 1000 )
            {
               /* set rate to 200 */
               error = SetSignalDataRate (p_signal,RATE_200HZ);
            }
            else
            {
               if( data_ratex10 > 500 )
               {
                  /* set rate to 100 */
                  error = SetSignalDataRate (p_signal,RATE_100HZ);
               }
               else
               {
                  /* set rate to 50 */
                  error = SetSignalDataRate (p_signal,RATE_50HZ);
               }
            }
   }
   else
   {
      if ( data_ratex10 > 10 )
      {
         /******************************/
         /* data rate between 1 and 20 */
         /******************************/
         if( data_ratex10 > 100 )
         {
            /* set rate to 20 */
            error = SetSignalDataRate (p_signal,RATE_20HZ);
         }
         else
         {
            if( data_ratex10 > 50 )
            {
               /* set rate to 10 */
               error = SetSignalDataRate (p_signal,RATE_10HZ);
            }
            else
            {
               if( data_ratex10 > 20 )
               {
                  /* set rate to 5 */
                  error = SetSignalDataRate (p_signal,RATE_5HZ);
               }
               else
               {
                  /* set rate to 2 */
                  error = SetSignalDataRate (p_signal,RATE_2HZ);
               }
            }
         }
      }
      else
      {
         /******************************/
         /* data rate less than 2 Hz   */
         /******************************/
         if( data_ratex10 > 5 )
         {
            /* set rate to 1 */
            error = SetSignalDataRate (p_signal,RATE_1HZ);
         }
         else
         {
            if( data_ratex10 > 2 )
            {
               /* set rate to .5 */
               error = SetSignalDataRate (p_signal,RATE_PT5HZ);
            }
            else
            {
               if( data_ratex10 > 1 )
               {
                  /* set rate to .2 */
                  error = SetSignalDataRate (p_signal,RATE_PT2HZ);
               }
               else
               {
                  /* set rate to .1 */
                  error = SetSignalDataRate (p_signal,RATE_PT1HZ);

               }
            }
         }
      }
   }
   return error;
}

/***********************************************************************/
/* END FUNCTION: SetDataRate                                           */
/***********************************************************************/





/***********************************************************************/
/* FUNCTION: GetDataRate                                               */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

U_INT32 GetDataRate(pSIG_TABLE  p_signal)
{
U_INT32   data_ratex10;
RATE_TYPE  rate;

   rate = GetSignalDataRate (p_signal);

   switch(rate)
   {
      case RATE_PT1HZ:
         data_ratex10 = 1;
         break;

      case  RATE_PT2HZ:
         data_ratex10 = 2;
         break;

      case  RATE_PT5HZ:
         data_ratex10 = 5;
         break;

      case  RATE_1HZ:
         data_ratex10 = 10;
         break;

      case RATE_2HZ :
         data_ratex10 = 20;
         break;

      case  RATE_5HZ :
         data_ratex10 = 50;
         break;

      case  RATE_10HZ :
         data_ratex10 = 100;
         break;

      case  RATE_20HZ :
         data_ratex10 = 200;
         break;

      case RATE_50HZ:
         data_ratex10 = 500;
         break;

      case RATE_100HZ:
         data_ratex10 = 1000;
         break;

      case RATE_200HZ:
         data_ratex10 = 2000;
            break;

      case RATE_500HZ:
         data_ratex10 = 5000;
            break;

      default:
         data_ratex10 = 200;

   }
   return  data_ratex10;
}

/***********************************************************************/
/* END FUNCTION: GetDataRate                                           */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: DoSxCD                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SxCD command.                                */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/



INT16 DoSxCD(U_INT8  signal, CMD_TYPE *p_cmd,BIT8  *p_resp_parm)
{

INT32             data_ratex10;
pSIG_TABLE        p_signal;
U_INT16           length;
UI_ERR            error;


   error = OK;
   length = 0;

   p_signal = (signal == SIGNAL1) ?  pSIGNAL1 :
              (signal == SIGNAL2) ?  pSIGNAL2 :  pSIGNALP;

   if ( (p_cmd->parmv[0] > 0) && (p_cmd->parms[p_cmd->parmv[1]] == '?') )
   {


      data_ratex10 = GetDataRate(p_signal);
      length = PutIntParam(data_ratex10, p_resp_parm, 1);

      length += PutAsciiParam((BIT8 *)",", p_resp_parm+length);

      switch (Acq_Mode[signal])
      {
      case CON:
         length += PutAsciiParam((BIT8 *)"CON", p_resp_parm+length);
         break;
      case RUN:
         length += PutAsciiParam((BIT8 *)"RUN", p_resp_parm+length);
         break;
      case SGL:
         length += PutAsciiParam((BIT8 *)"SGL", p_resp_parm+length);
         break;
      }

      length += PutAsciiParam((BIT8 *)",", p_resp_parm+length);

      switch (Data_Format[signal])
      {
      case BIN:
         length += PutAsciiParam((BIT8 *)"BIN", p_resp_parm+length);
         break;
      case HEX:
         length += PutAsciiParam((BIT8 *)"HEX", p_resp_parm+length);
         break;
      case DEC:
         length += PutAsciiParam((BIT8 *)"DEC", p_resp_parm+length);
         break;
      case CMP:
         length += PutAsciiParam((BIT8 *)"CMP", p_resp_parm+length);
         break;
      }

      return length;
   }
   else
   {
      switch ( p_cmd->parmv[0] )
      {
      default:
      case 3:
         if( StrLen( &p_cmd->parms[p_cmd->parmv[3]]) != 0 )
         {
            /* Set Data Format */
            switch (p_cmd->parms[p_cmd->parmv[3]])
            {
            case 'B':
               Data_Format[signal] = BIN;
               break;
            case 'H':
               Data_Format[signal] = HEX;
               break;
            case 'D':
               Data_Format[signal] = DEC;
               break;
            case 'C':
               Data_Format[signal] = CMP;
               break;
            default:
               error = INVALID_PARAM;
               CmdErrorHandler(p_cmd, 3, error);
            }
         }
         /* fall through to check next parameter */
      case 2:
         if( StrLen( &p_cmd->parms[p_cmd->parmv[2]]) != 0 )
         {
            /* Set Data Acq Mode */
            switch (p_cmd->parms[p_cmd->parmv[2]])
            {
            case 'C':
               Acq_Mode[signal] = CON;
               break;
            case 'R':
               Acq_Mode[signal] = RUN;
               break;
            case 'S':
               Acq_Mode[signal] = SGL;
               break;
            default:
               error = INVALID_PARAM;
               CmdErrorHandler(p_cmd, 2, error);
            }
         }
         /* fall through to check next parameter */
      case 1:
         if( StrLen( &p_cmd->parms[p_cmd->parmv[1]]) != 0 )
         {
            /* Set Data Rate */
            if( ISDIGIT(p_cmd->parms[p_cmd->parmv[1]]) ||
                    (p_cmd->parms[p_cmd->parmv[1]] == '.') )
            {
               error=DecToInt(&p_cmd->parms[p_cmd->parmv[1]],1,&data_ratex10);
               if(error != OK)
               {
                  CmdErrorHandler(p_cmd,1,error);
                  return NO_RESPONSE;
               }
               error = SetDataRate(p_signal, data_ratex10);
               if(error != OK)
               {
                  CmdErrorHandler(p_cmd,1,error);
                  return NO_RESPONSE;
               }

            }
            else
            {
               error = INVALID_PARAM;
               CmdErrorHandler(p_cmd, 1, error);
            }
         }
         break;
      case 0:
         /* error - number of parameters */
         error = PARAM_SYNTAX;
         CmdErrorHandler(p_cmd, 1, error);
         return NO_RESPONSE;
      }
      return  NO_RESPONSE;
   }
}

/***********************************************************************/
/* END FUNCTION: DoSxCD                                                */
/***********************************************************************/





/***********************************************************************/
/* FUNCTION: DoSxCS                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SxCS command.                                */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/


INT16 DoSxCS(U_INT8  signal, CMD_TYPE *p_cmd,BIT8  *p_resp_parm)
{

pSIG_TABLE        p_signal;
INT32             signal_type;
INT32             mem_loc;
INT16             length;
UI_ERR            error;
BIT8              data_size[2];


   error = OK;

   p_signal = (signal == SIGNAL1) ?  pSIGNAL1 :
              (signal == SIGNAL2) ?  pSIGNAL2 :  pSIGNALP;

   if ( (p_cmd->parmv[0] > 0) && (p_cmd->parms[p_cmd->parmv[1]] == '?') )
   {
      /* get signal type */
      signal_type = GetSignalType(p_signal);
      if ( (SIG_TYPE) signal_type == MEMORY_LOCATION )
      {
         mem_loc = GetSignalMemLocAddr(p_signal);
         data_size[1] = 0;
         switch ( GetSignalMemLocSize(p_signal) )
         {
         case SIZE_32_BIT:
            data_size[0] = 'L';
            break;
         case SIZE_16_BIT:
            data_size[0] = 'U';
            break;
         case SIZE_16_BIT_SIGNED:
            data_size[0] = 'W';
            break;
         case SIZE_8_BIT:
            data_size[0] = 'O';
            break;
         case SIZE_8_BIT_SIGNED:
            data_size[0] = 'B';
            break;
         default:
            data_size[0] = 'L';
            break;
         }
         length = PutAsciiParam((BIT8 *)data_size,p_resp_parm);
         length += PutHexParam((U_INT32)mem_loc,(BIT8 *)(p_resp_parm+1));
         return  length;
      }
      else
      {
         length = PutAsciiParam((BIT8 *)"A",p_resp_parm);
         length += PutIntParam(signal_type,p_resp_parm+1,0);
         return  length;
      }
   }
   else
   {
      if( p_cmd->parmv[0] > 0 )
      {
         /* check if setting signal */
         switch (p_cmd->parms[0])
         {
            case 'A':
               if( !(error = DecToInt(&(p_cmd->parms[1]),0,&signal_type )) )
               {
                  error = SetSignalType(p_signal,(SIG_TYPE) signal_type);
               }
               break;
            case 'B':
               if(!(error = HexToInt(&(p_cmd->parms[1]),(U_INT32 *)&mem_loc)))
               {
                  error =SetSignalMemLoc(p_signal,(DATA_SIZE)SIZE_8_BIT_SIGNED,
                                          (U_INT32 *)mem_loc);
               }
               break;
            case 'O':
               if(!(error = HexToInt(&(p_cmd->parms[1]),(U_INT32 *)&mem_loc)))
               {
                  error = SetSignalMemLoc(p_signal, (DATA_SIZE)SIZE_8_BIT,
                                          (U_INT32 *)mem_loc);
               }
               break;
            case 'W':
               if(!(error = HexToInt(&(p_cmd->parms[1]),(U_INT32 *)&mem_loc)))
               {
                  error=SetSignalMemLoc(p_signal,(DATA_SIZE)SIZE_16_BIT_SIGNED,
                                          (U_INT32 *)mem_loc);
               }
               break;
            case 'U':
               if( !(error=HexToInt(&(p_cmd->parms[1]),(U_INT32 *)&mem_loc)) )
               {
                  error = SetSignalMemLoc(p_signal, (DATA_SIZE)SIZE_16_BIT,
                                          (U_INT32 *)mem_loc);
               }
               break;
            case 'L':
               if( !(error=HexToInt(&(p_cmd->parms[1]),(U_INT32 *)&mem_loc)) )
               {
                  error = SetSignalMemLoc(p_signal, (DATA_SIZE)SIZE_32_BIT,
                                          (U_INT32 *)mem_loc);
               }
               break;
            default:
               error = INVALID_PARAM;
               break;
         }
      }
      else
      {
         /* number of parameters error */
         error = INSTR_SYNTAX;
      }
      CmdErrorHandler(p_cmd, 1, error);
      return  NO_RESPONSE;
   }
}

/***********************************************************************/
/* END FUNCTION: DoSxCS                                                */
/***********************************************************************/

/***********************************************************************/
/* FUNCTION: DoSxST                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the status (SxST) command for the signal path.   */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/***********************************************************************/

INT16 DoSxST(U_INT8  signal, CMD_TYPE *p_cmd,BIT8  *p_resp_parm)
{

U_INT16           length;
U_INT32           points_remaining;


   (void)p_cmd;
   length = 0;


   /* is acquisition on? */
   if (Acq_On[signal] == TRUE)
   {
      length = PutAsciiParam((BIT8 *)"1", p_resp_parm+length);
   }
   else
   {
      length = PutAsciiParam((BIT8 *)"0", p_resp_parm+length);
   }

   /* is there a buffer overflow condition? */
   length += PutAsciiParam((BIT8 *)",", p_resp_parm+length);
   if (SigBuf_Overflow[signal] == TRUE)
   {
      length += PutAsciiParam((BIT8 *)"1", p_resp_parm+length);
   }
   else
   {
      length += PutAsciiParam((BIT8 *)"0", p_resp_parm+length);
   }

   /* how many points remain in instrument buffer? */
   length += PutAsciiParam((BIT8 *)",", p_resp_parm+length);
   INTERRUPTS_OFF;
      points_remaining = SigBuf_Point_Count[signal]
                              + (U_INT32)FrmtBuf_Point_Count[signal];
   INTERRUPTS_ON;
   length += PutIntParam(points_remaining, p_resp_parm+length, 0);


   return(length);
}

/***********************************************************************/
/* END FUNCTION: DoSxST                                                */
/***********************************************************************/


/***********************************************************************/
/* FUNCTION: DoSx99                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Test command used for development.                         */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 DoSx99(U_INT8  signal, CMD_TYPE *p_cmd,BIT8  *p_resp_parm)
{
INT16   parm_len;
INT32   number;
INT16   parameter;
INT16   signif_dig;
UI_ERR   error;



   (void)signal;
   (void)p_cmd;


   signif_dig = 0;
   parameter = 1;
   error = DecToInt(GetCmdParm(parameter),signif_dig, &number);
   parm_len = PutIntParam(number,p_resp_parm,signif_dig);

   parm_len += PutAsciiParam((BIT8 *)",",p_resp_parm+parm_len);

   signif_dig = 1;
   parameter = 1;
   error = DecToInt(GetCmdParm(parameter),signif_dig, &number);
   parm_len += PutIntParam(number,p_resp_parm/*+parm_len*/,signif_dig);

   parm_len += PutAsciiParam((BIT8 *)",",p_resp_parm+parm_len);

/*
   signif_dig = 2;
   parameter = 1;
   error = DecToInt(GetCmdParm(parameter),signif_dig, &number);
   parm_len += PutIntParam(number,p_resp_parm+parm_len,signif_dig);


   parm_len += PutAsciiParam((BIT8 *)",",p_resp_parm+parm_len);

   signif_dig = 3;
   parameter = 1;
   error = DecToInt(GetCmdParm(parameter),signif_dig, &number);
   parm_len += PutIntParam(number,p_resp_parm+parm_len,signif_dig);


   parm_len += PutAsciiParam((BIT8 *)",",p_resp_parm+parm_len);

   signif_dig = 4;
   parameter = 1;
   error = DecToInt(GetCmdParm(parameter),signif_dig, &number);
   parm_len += PutIntParam(number,p_resp_parm+parm_len,signif_dig);

   parm_len += PutAsciiParam((BIT8 *)",",p_resp_parm+parm_len);

   signif_dig = 5;
   parameter = 1;
   error = DecToInt(GetCmdParm(parameter),signif_dig, &number);
   parm_len += PutIntParam(number,p_resp_parm+parm_len,signif_dig);
   */

   switch (error)
   {
   case OK:
      parm_len += PutAsciiParam((BIT8 *)" OK",p_resp_parm+parm_len);
      break;
   case MISSING_PARAM:
      parm_len += PutAsciiParam((BIT8 *)" MISSING_PARAM",p_resp_parm+parm_len);
      break;
   case PARAM_TOO_LARGE:
      parm_len +=PutAsciiParam((BIT8 *)" PARAM_TOO_LARGE",p_resp_parm+parm_len);
      break;
   default:
      parm_len +=PutAsciiParam((BIT8 *)" unknown failure",p_resp_parm+parm_len);
      break;
   }

   /*
   parm_len = PutAsciiParam((BIT8 *)"",p_resp_parm);
   parm_len += PutAsciiParam((BIT8 *)",",p_resp_parm+parm_len);
   parm_len += PutAsciiParam((BIT8 *)"TEST2",p_resp_parm+parm_len);
   parm_len += PutAsciiParam((BIT8 *)",",p_resp_parm+parm_len);
   parm_len += PutAsciiParam((BIT8 *)"TEST3",p_resp_parm+parm_len);
   parm_len += PutAsciiParam((BIT8 *)",",p_resp_parm+parm_len);
   parm_len += PutAsciiParam((BIT8 *)"TEST4",p_resp_parm+parm_len);
   */

   return  parm_len;
}

/***********************************************************************/
/* END FUNCTION: DoSx99                                                */
/***********************************************************************/




/***********************************************************************/
/* FUNCTION: DoSxXX                                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Implement the SxXX command.                                */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

/*
INT16 DoSxXX(U_INT8  signal, CMD_TYPE *p_cmd,BIT8  *p_resp_parm)
{
INT16   parm_len;


   Do function here ......


   return  parm_len;
}
*/

/***********************************************************************/
/* END FUNCTION: DoSxXX                                                */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: DeferRead                                                 */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Handle deferred form of SxRD                               */
/*                                                                     */
/* RETURNED VALUE: TRUE if deferred                                    */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

TRUE_FALSE DeferRead (U_INT8  signal, CMD_TYPE  *p_cmd)
{
   pRD_PENDING       prd_pending;
   INT32             req_num_pts;
   INT32             delay_time;
   UI_ERR            error;

   /* not deferred form if no timeout value */
   if ( (p_cmd->parmv[0]) < 2)
   {
      return False;
   }

   /**********************************************************************/
   /**********      Determine Number Of Points Requested       ***********/
   /**********************************************************************/

   /* determine number of requested points from the 1st parameter of command */
   if( StrLen( &p_cmd->parms[p_cmd->parmv[1]]) != 0 )
   {
      error = DecToInt( &p_cmd->parms[p_cmd->parmv[1]],0,&req_num_pts );
      if(error != OK)
      {
         /* if error, let the normal routine handle it */
         return False;
      }
   }
   else
   /* number of points not given, default to 1 */
   {
      req_num_pts = 1;
   }

   /**********************************************************************/
   /**********      Determine Delay Time in Milliseconds       ***********/
   /**********************************************************************/

   /* determine delay time from the 2nd parameter of command */
   if( StrLen( &p_cmd->parms[p_cmd->parmv[2]]) != 0 )
   {
      error = DecToInt( &p_cmd->parms[p_cmd->parmv[2]],0,&delay_time );
      if(error != OK)
      {
         CmdErrorHandler(p_cmd,2,error);
         return True;
      }
   }
   else
   /* delay time not given */
   {
      return False;
   }

   if ( delay_time <= 0 )
   {
      error = INVALID_PARAM;
      CmdErrorHandler(p_cmd,2,error);
      return True;
   }

   if ( delay_time > 60000 )
   {
      error = PARAM_TOO_LARGE;
      CmdErrorHandler(p_cmd,2,error);
      return True;
   }

   /* convert delay time in mSec to 512'ths of a second */
   delay_time = delay_time * 512 / 1000;

   /* point to the appropriate structure */
   prd_pending = (signal == SIGNAL1)?&Signal1_Rd_Pending:
                 (signal == SIGNAL2)?&Signal2_Rd_Pending:&SignalP_Rd_Pending;

   /* if already pending for this channel then error */
   if ( prd_pending->pending == TRUE )
   {
      error = NOT_ALLOWED;
      CmdErrorHandler(p_cmd,2,error);
      return True;
   }

   /* fill in the values to be used later */
   prd_pending->comm_port = p_cmd->comm_port;
   prd_pending->dsap = p_cmd->dsap.int_dsap;
   prd_pending->ssap = p_cmd->ssap.int_ssap;
   prd_pending->opcode = p_cmd->opcode.int_op;
   prd_pending->points = req_num_pts;
   prd_pending->timeout = Tick_512_Counter + (U_INT16)delay_time;
   prd_pending->pending = TRUE;

   /* report that the command has been deferred */
   return True;

}

/***********************************************************************/
/* END FUNCTION: DeferRead                                             */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: CheckRdPending                                            */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Check for pending signal read and re-queue if ready        */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

void CheckRdPending (U_INT8 signal)
{
   pRD_PENDING prd_pending;
   INT16       time_remaining;
   U_INT16     length;
   CMD_TYPE    *p_cmd;

   prd_pending = (signal == SIGNAL1)?&Signal1_Rd_Pending:
                 (signal == SIGNAL2)?&Signal2_Rd_Pending:&SignalP_Rd_Pending;

   /* do nothing if there is no pending read */
   if ( prd_pending->pending != TRUE )
   {
      return;
   }

   /* see how much time, if any, until timeout */
   time_remaining = (prd_pending->timeout - Tick_512_Counter);

   /* do nothing if less than the requested number of points */
   /* and no timeout                                         */
   if ( ( SigBuf_Point_Count[signal] < prd_pending->points) &&
        ( time_remaining > 0) )
   {
      return;
   }

   /* time to regenerate the original command but without the delay */
   /* is there a cmd buf available */
   INTERRUPTS_OFF;
   if ( Free_Cmd_Q.num_entries <= 2 )  /* save 2 cmd bufs for workfile */
   {
      /* no Free_Cmd available, do nothing this time */
      INTERRUPTS_ON;
      return;
   }
   else
   {
      GetCmdSafe ( p_cmd, Free_Cmd_Q );
      INTERRUPTS_ON;
   }

   /* simulate a new command using values from the old command */
   p_cmd->comm_port = prd_pending->comm_port;
   p_cmd->dsap.int_dsap = prd_pending->dsap;
   p_cmd->ssap.int_ssap = prd_pending->ssap;
   p_cmd->opcode.int_op = prd_pending->opcode;
   p_cmd->opcode.char_op[2] = 0;
   p_cmd->parmv[0] = 1;
   p_cmd->parmv[1] = 0;
   length = IntToDec ( prd_pending->points, &p_cmd->parms[0] );
   p_cmd->parms[length] = 0;

   /* finally, append the command to the appropriate queue */
   if ( signal == SIGNAL1 )
   {
      AppendCmd ( p_cmd, S1_Cmd_Q );
   }
   else
   {
      AppendCmd ( p_cmd, S2_Cmd_Q );
   }

   /* close the pending read */
   prd_pending->pending = FALSE;

}

/***********************************************************************/
/* END FUNCTION: CheckRdPending                                        */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: S1Opcodes                                                 */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: calls routines needed to implement the S1 commands.        */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 S1Opcodes(CMD_TYPE  *p_cmd,BIT8  *p_resp_parm,U_INT16 max_resp_len)
{
INT16           parm_len;

   parm_len = NO_RESPONSE;
   switch (p_cmd->opcode.int_op)
   {
      case  MAKEINT('R','S'):
        parm_len = DoSxRS(SIGNAL1);
        break;
      case  MAKEINT('R','D'):
        if ( SigBuf_Overflow[SIGNAL1] == TRUE )
        {
           /* Exception if try to read from a buffer after it has overflowed */
           SetNewException (SIGBUF1_OVERFLOW, 0, 0);
        }
        if ( DeferRead (SIGNAL1, p_cmd ) )
        {
           return NO_RESPONSE;
        }
        switch (Data_Format[SIGNAL1])
        {
           case BIN:
              parm_len = DoSxRDBin(SIGNAL1, p_cmd, p_resp_parm,max_resp_len);
              break;
           case HEX:
              parm_len = DoSxRDHexDec(SIGNAL1, p_cmd, p_resp_parm,max_resp_len);
              break;
           case DEC:
              parm_len = DoSxRDHexDec(SIGNAL1, p_cmd, p_resp_parm,max_resp_len);
              break;
           case CMP:
              parm_len = DoSxRDCmp(SIGNAL1, p_cmd, p_resp_parm,max_resp_len);
              break;
        }
        break;
      case  MAKEINT('S','R'):
        parm_len = DoSxSR(SIGNAL1);
        break;
      case  MAKEINT('S','P'):
        parm_len = DoSxSP(SIGNAL1);
        break;
      case  MAKEINT('C','D'):
        parm_len = DoSxCD(SIGNAL1, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('C','S'):
        parm_len = DoSxCS(SIGNAL1, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('S','T'):
        parm_len = DoSxST(SIGNAL1, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('C','A'):
        parm_len = DoCmd(p_cmd, p_resp_parm, &mS1CA);
        break;
      case  MAKEINT('Z','A'):
        parm_len = DoCmd(p_cmd, p_resp_parm, &mS1ZA);
        break;
      case  MAKEINT('S','F'):
        parm_len = DoStatus(p_cmd, p_resp_parm, &mS1SF);
        break;
      case  MAKEINT('9','9'):
        parm_len = DoSx99(SIGNAL1, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('E','O'):
        parm_len = DoSXEO(p_cmd,p_resp_parm);
        break;
      default:
         /* bad command opcode */
         parm_len = NO_RESPONSE;
         break;
   }

   return parm_len;
}


/***********************************************************************/
/* END FUNCTION: S1Opcodes                                             */
/***********************************************************************/



/***********************************************************************/
/* FUNCTION: S1_Cmds                                                   */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: calls function which executes a command if one is          */
/*          available on the command queue.                            */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

void S1_Cmds(void)
{
   CheckRdPending(SIGNAL1);
   ExecCmds(&S1_Cmd_Q,S1Opcodes);
}

/***********************************************************************/
/* END FUNCTION: S1_Cmds                                               */
/***********************************************************************/


/***********************************************************************/
/* FUNCTION: S2Opcodes                                                 */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: calls routines needed to implement the S2 commands.        */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 S2Opcodes(CMD_TYPE  *p_cmd,BIT8  *p_resp_parm,U_INT16 max_resp_len)
{
INT16           parm_len;

   parm_len = NO_RESPONSE;
   switch (p_cmd->opcode.int_op)
   {
      case  MAKEINT('R','S'):
        parm_len = DoSxRS(SIGNAL2);
        break;
      case  MAKEINT('R','D'):
        if ( SigBuf_Overflow[SIGNAL2] == TRUE )
        {
           /* Exception if try to read from a buffer after it has overflowed */
           SetNewException (SIGBUF2_OVERFLOW, 0, 0);
        }
        if ( DeferRead (SIGNAL2, p_cmd ) )
        {
           return NO_RESPONSE;
        }
        switch (Data_Format[SIGNAL2])
        {
           case BIN:
              parm_len = DoSxRDBin(SIGNAL2, p_cmd, p_resp_parm,max_resp_len);
              break;
           case HEX:
              parm_len = DoSxRDHexDec(SIGNAL2, p_cmd, p_resp_parm,max_resp_len);
              break;
           case DEC:
              parm_len = DoSxRDHexDec(SIGNAL2, p_cmd, p_resp_parm,max_resp_len);
              break;
           case CMP:
              parm_len = DoSxRDCmp(SIGNAL2, p_cmd, p_resp_parm,max_resp_len);
              break;
        }
        break;
      case  MAKEINT('S','R'):
        parm_len = DoSxSR(SIGNAL2);
        break;
      case  MAKEINT('S','P'):
        parm_len = DoSxSP(SIGNAL2);
        break;
      case  MAKEINT('C','D'):
        parm_len = DoSxCD(SIGNAL2, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('C','S'):
        parm_len = DoSxCS(SIGNAL2, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('S','T'):
        parm_len = DoSxST(SIGNAL2, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('C','A'):
        parm_len = DoCmd(p_cmd, p_resp_parm, &mS2CA);
        break;
      case  MAKEINT('Z','A'):
        parm_len = DoCmd(p_cmd, p_resp_parm, &mS2ZA);
        break;
      case  MAKEINT('S','F'):
        parm_len = DoStatus(p_cmd, p_resp_parm, &mS2SF);
        break;
      case  MAKEINT('9','9'):
        parm_len = DoSx99(SIGNAL2, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('E','O'):
        parm_len = DoSXEO(p_cmd,p_resp_parm);
        break;
      default:
         /* bad command opcode */
         parm_len = NO_RESPONSE;
         CmdErrorHandler(p_cmd,0,INVALID_OP);
         break;
   }
   return parm_len;
}


/***********************************************************************/
/* END FUNCTION: S2Opcodes                                             */
/***********************************************************************/


/***********************************************************************/
/* FUNCTION: S2_Cmds                                                   */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: calls function which executes a command if one is          */
/*          available on the command queue.                            */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

void S2_Cmds(void)
{
   CheckRdPending(SIGNAL2);
   ExecCmds(&S2_Cmd_Q,S2Opcodes);
}

/***********************************************************************/
/* END FUNCTION: S2_Cmds                                               */
/***********************************************************************/




/***********************************************************************/
/* FUNCTION: SPOpcodes                                                 */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: calls routines needed to implement the SP commands.        */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 SPOpcodes(CMD_TYPE  *p_cmd,BIT8  *p_resp_parm,U_INT16 max_resp_len)
{
INT16           parm_len;


   parm_len = NO_RESPONSE;
   switch (p_cmd->opcode.int_op)
   {
      case  MAKEINT('R','S'):
        parm_len = DoSxRS(SIGNALP);
        break;
      case  MAKEINT('R','D'):
        switch (Data_Format[SIGNALP])
        {
           case BIN:
              parm_len = DoSxRDBin(SIGNALP, p_cmd, p_resp_parm,max_resp_len);
              break;
           case HEX:
              parm_len = DoSxRDHexDec(SIGNALP, p_cmd, p_resp_parm,max_resp_len);
              break;
           case DEC:
              parm_len = DoSxRDHexDec(SIGNALP, p_cmd, p_resp_parm,max_resp_len);
              break;
           case CMP:
              parm_len = DoSxRDCmp(SIGNALP, p_cmd, p_resp_parm,max_resp_len);
              break;
        }
        break;
      case  MAKEINT('S','R'):
        parm_len = DoSxSR(SIGNALP);
        break;
      case  MAKEINT('S','P'):
        parm_len = DoSxSP(SIGNALP);
        break;
      case  MAKEINT('C','D'):
        parm_len = DoSxCD(SIGNALP, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('C','S'):
        parm_len = DoSxCS(SIGNALP, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('S','T'):
        parm_len = DoSxST(SIGNALP, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('C','A'):
        parm_len = DoCmd(p_cmd, p_resp_parm, &mSPCA);
        break;
      case  MAKEINT('Z','A'):
        parm_len = DoCmd(p_cmd, p_resp_parm, &mSPZA);
        break;
      case  MAKEINT('S','F'):
        parm_len = DoStatus(p_cmd, p_resp_parm, &mSPSF);
        break;
      case  MAKEINT('9','9'):
        parm_len = DoSx99(SIGNALP, p_cmd, p_resp_parm);
        break;
      case  MAKEINT('E','O'):
        parm_len = DoSXEO(p_cmd,p_resp_parm);
        break;
      default:
         /* bad command opcode */
         parm_len = NO_RESPONSE;
         CmdErrorHandler(p_cmd,0,INVALID_OP);
         break;
   }
   return parm_len;
}


/***********************************************************************/
/* END FUNCTION: SPOpcodes                                             */
/***********************************************************************/


/***********************************************************************/
/* FUNCTION: SP_Cmds                                                   */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: calls function which executes a command if one is          */
/*          available on the command queue.                            */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

void SP_Cmds(void)
{
   CheckRdPending(SIGNALP);
   ExecCmds(&SP_Cmd_Q,SPOpcodes);
}

/***********************************************************************/
/* END FUNCTION: SP_Cmds                                               */
/***********************************************************************/




/***********************************************************************/
/* FUNCTION: SSOpcodes                                                 */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: calls routines needed to implement the SS commands.        */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

INT16 SSOpcodes(CMD_TYPE  *p_cmd,BIT8  *p_resp_parm,U_INT16 max_resp_len)
{
INT16           parm_len;


   (void)p_resp_parm;  /* no used in this function */
   (void)max_resp_len;  /* no used in this function */

   parm_len = NO_RESPONSE;
   switch (p_cmd->opcode.int_op)
   {
      case  MAKEINT('R','S'):
        parm_len = DoSSRS();
        break;
      case  MAKEINT('S','R'):
        parm_len = DoSSSR();
        break;
      case  MAKEINT('S','P'):
        parm_len = DoSSSP();
        break;
      case  MAKEINT('D','T'):
        parm_len = DoSSDT();
        break;
      case  MAKEINT('E','O'):
        parm_len = DoSXEO(p_cmd,p_resp_parm);
        break;
      default:
         /* bad command opcode */
         parm_len = NO_RESPONSE;
         CmdErrorHandler(p_cmd,0,INVALID_OP);
         break;
   }
   return parm_len;
}


/***********************************************************************/
/* END FUNCTION: SSOpcodes                                             */
/***********************************************************************/

/***********************************************************************/
/* FUNCTION: SS_Cmds                                                   */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: calls function which executes a command if one is          */
/*          available on the command queue.                            */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* FILE SCOPE STATICS USED:                                            */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*     Order of execution for the S1, S2, and SS commands are not      */
/*     guaranteed.  If the SS commands are required for                */
/*     synchronization do not use the individual S1 and S2 commands    */
/*     for starting and stopping and resetting the signal.             */
/*                                                                     */
/* WARNINGS:                                                           */
/*                                                                     */
/***********************************************************************/

void SS_Cmds(void)
{
   ExecCmds(&SS_Cmd_Q,SSOpcodes);
}

/***********************************************************************/
/* END FUNCTION: SS_Cmds                                               */
/***********************************************************************/




